package com.seres.user.service.role;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.seres.client.mapper.user.SysRoleMapper;
import com.seres.client.mapper.user.SysRoleMenuMapper;
import com.seres.client.mapper.user.SysUserRoleMapper;
import com.seres.client.model.user.*;
import com.seres.user.cache.DeptCache;
import com.seres.enums.OftenEnum;
import com.seres.enums.RedisCacheEnum;
import com.seres.redis.RedisCache;
import com.seres.redis.RedisTableCache;
import com.seres.user.vo.user.RoleVo;
import com.seres.util.StringUtils;
import com.seres.util.ThreadPool;
import com.seres.util.ValidatorTools;
import com.seres.vo.AuthUserInfo;
import com.seres.vo.UserInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Tan-Bowen
 * @version 1.0
 * @description TODO
 * @date 2021/8/13 10:23
 */
@Slf4j
@Service
public class RoleServiceImpl implements IRoleService {

    @Resource
    private SysRoleMapper roleMapper;

    @Resource
    private SysRoleMenuMapper roleMenuMapper;

    @Resource
    private SysUserRoleMapper userRoleMapper;

    @Resource
    private RedisTableCache redisTableCache;

    @Resource
    private RedisCache redisCache;

    @Resource
    private ThreadPool threadPool;

    @Resource
    private DeptCache deptCache;

    @Override
    public IPage<RoleVo.PageList> rolePage(Page<SysRole> page, RoleVo.Select select) {
        UserInfo userInfo = AuthUserInfo.getUser();
        LambdaQueryWrapper<SysRole> query = new LambdaQueryWrapper<>();
        query.eq(select.getDeptId() != null, SysRole::getDeptId, select.getDeptId());
        // 只能读取当前和子级的部门信息
        query.in(!userInfo.getDeptIds().isEmpty(), SysRole::getDeptId, userInfo.getDeptIds());
        query.eq(select.getState() != null, SysRole::getState, select.getState());
        query.like(StringUtils.isNotBlank(select.getName()), SysRole::getName, select.getName());
        IPage<RoleVo.PageList> roles = roleMapper.selectPage(page, query).convert(dept -> BeanUtil.copyProperties(dept, RoleVo.PageList.class));
        roles.getRecords().forEach(e -> {
            e.setDeptName(deptCache.deptNameMap().getOrDefault(e.getDeptId(),e.getDeptId()==0?"管理组":""));
            SysUser user = redisTableCache.get(SysUser.class, e.getCreateUser());
            if (user != null) {
                e.setCreateName(user.getUserName());
            }
        });
        return roles;
    }

    @Override
    public void create(RoleVo.Create create) {
        SysRole role = BeanUtil.copyProperties(create, SysRole.class);
        ValidatorTools.checkSqlSuccess(roleMapper.insert(role), "新增角色失败");
    }

    @Override
    public void update(RoleVo.Update update) {
        SysRole role = BeanUtil.copyProperties(update, SysRole.class);
        ValidatorTools.checkSqlSuccess(roleMapper.updateById(role), "编辑角色失败");
        redisTableCache.remove(SysRole.class, update.getId());
    }


    @Override
    public List<RoleVo.PageList> getDeptRole() {
        List<Long> deptIds = AuthUserInfo.getDeptIds();
        LambdaQueryWrapper<SysRole> query = new LambdaQueryWrapper<>();
        query.eq(SysRole::getState, OftenEnum.EnableState.ENABLE.code());
        query.in(!deptIds.isEmpty(), SysRole::getDeptId, deptIds);
        List<SysRole> roles = roleMapper.selectList(query);
        List<RoleVo.PageList> res = new ArrayList<>();
        roles.forEach(role -> {
            RoleVo.PageList obj = BeanUtil.copyProperties(role, RoleVo.PageList.class);
            if (!ValidatorTools.isSuper(role.getDeptId())) {
                SysDept dept = redisTableCache.get(SysDept.class, role.getDeptId());
                if (dept != null) {
                    obj.setDeptName(dept.getName());
                    obj.setDeptPid(dept.getPid());
                }
            } else {
                obj.setDeptName("系统管理组");
                obj.setDeptId(Long.valueOf(OftenEnum.Super.SUPER_MAN.code()));
            }
            res.add(obj);
        });

        return res;
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void settingRolePower(Long roleId, List<Long> powers) {
        LambdaQueryWrapper<SysRoleMenu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRoleMenu::getRoleId, roleId);
        roleMenuMapper.delete(wrapper);
        powers.forEach(menu -> {
            SysRoleMenu roleMenu = SysRoleMenu.builder().roleId(roleId).menuId(menu).build();
            ValidatorTools.checkSqlSuccess(roleMenuMapper.insert(roleMenu), "修改角色权限失败!");
        });
        // 清理 用戶、角色的菜单权限缓存
        redisCache.del(RedisCacheEnum.ROLE_MENU.createKey(roleId));

    }


    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void deleteRole(Long roleId){
        ValidatorTools.checkSqlSuccess(this.roleMapper.deleteById(roleId),"删除用户失败！");
        // 删除角色菜单
        this.roleMenuMapper.delete(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId,roleId));
        this.userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getRoleId,roleId));
        redisTableCache.remove(SysRole.class,roleId);
        redisCache.del(RedisCacheEnum.USER_ROLE.createKey(roleId));
    }
}
